home *** CD-ROM | disk | FTP | other *** search
- Path: xanth!mcnc!rutgers!tut.cis.ohio-state.edu!cwjcc!hal!ncoast!allbery
- From: jfh@rpp386.UUCP (The Beach Bum)
- Newsgroups: comp.sources.misc
- Subject: v04i020: /etc/crash utility for SCO Xenix 2.2.1
- Message-ID: <8808111148.AA12910@rpp386.UUCP>
- Date: 11 Aug 88 16:48:27 GMT
- Sender: allbery@ncoast.UUCP
- Reply-To: jfh@rpp386.UUCP (The Beach Bum)
- Lines: 1539
- Approved: allbery@ncoast.UUCP
-
- Posting-number: Volume 4, Issue 20
- Submitted-by: "The Beach Bum" <jfh@rpp386.UUCP>
- Archive-name: sco-crash
-
- This is the initial release of my SCO Xenix crash utility. It is intended
- to replace the crash(1) command which SCO did not include.
-
- This command is known to run on only SCO Xenix 2.2.1. The only parts which
- should need adjustment for most reasonable UNIX(R) systems are the user
- page and process table entry routines. A Plexus System V port is in the
- works for you and should be available Real Soon Now ;-)
-
- [Plexus System III and System V both have working crash utilities. ++bsa]
-
- - John.
- --
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create:
- # README
- # Makefile
- # crash.c
- # interact.c
- # files.c
- # inodes.c
- # mounts.c
- # procs.c
- # texts.c
- # user.c
- # vars.c
- # stats.c
- # bufs.c
- # crash.h
- # This archive created: Thu Aug 11 11:45:59 1988
- # By: The Beach Bum (HASA, "S" Division)
- export PATH; PATH=/bin:/usr/bin:$PATH
- if test -f 'README'
- then
- echo shar: "will not over-write existing file 'README'"
- else
- cat << \SHAR_EOF > 'README'
- crash(1L) Version 1.0 08/11/88
-
- Introduction
-
- Crash is a utility for examining kernel tables while the system is
- running, or if there is a facility for taking crash dumps, examining the
- system after it has crashed. SCO does not provide a crash dump facility
- at this time, so that functionality is not present.
-
- The kernel structures which can be examined at present are:
-
- block buffer headers
- open file table entries
- active inode table entries
- mounted file system table entries
- process table entries
- system statistics such as name, version, age
- active and sticky bit text table entries
- per process user page information
- tunable parameters
-
- Using this information, it is possible to determine what files a given
- process is using, what device they reside on, who owns them and where
- the file pointer is currently positioned. Other information on running
- processes may also be determined.
-
- This version of crash differs from most other versions, such as that
- produced by AT&T for their UNIX(tm) systems, in that swapped user pages
- may be printed and the name for swapped processes is given. Also, not
- all of the aliases which are listed in the manual page from AT&T are
- provided. A number of commands have been left out, and some of the
- options for the included commands have been omitted as well.
-
- Commands
-
- Most commands take a list of table entries, which if not present
- defaults to all elements in the table.
-
- Print Buffer Headers
- Syntax: buf, b
-
- Prints the selected block buffer headers.
-
- Example:
- > buf 0 1 2 3 4
- BUF MAJ MIN BLOCK FLAGS
- 0 001 0047 20925 read done
- 1 001 0037 2817 read done
- 2 001 0050 2801 read done
- 3 001 0037 15175 read done
- 4 001 0050 6 done
-
- Print Open File Table Entries
- Syntax: file, f
-
- Prints the selected open file table entries, with cross references
- to the associated inodes, and the current file pointer.
-
- Example:
- > file 0 1 2 3 4
- SLOT FLAG COUNT INODE OFFSET
- 0 001 R 1 9 0
- 1 003 RW 3 3 18
- 2 003 RW 7 11 26800
- 3 002 W 2 4 169
- 4 001 R 1 8 0
-
- Display Command Summary
- Syntax: help, h, ?
-
- Prints the list of currently available commands and the aliases
- for them.
-
- Example:
- > help
- command summary
-
- buf (b) - buffer headers
- file (f) - open files
- help (h,?) - list commands
- inode (ino,i) - active inodes
- mount (m) - mounted file systems
- proc (p) - active and defunct processes
- quit (q,^D) - exit crash
- stat (s) - crash statistics, age, time
- text (t) - active and sticky bit text segments
- user (u) - user page information
- var (v) - tunable parameters
-
- Display Active Inode Table Entries
- Syntax: inode, ino, i
-
- Prints selected active inode table entries giving device, file
- size, permissions, and owners. Cross referenced from mount and
- file tables.
-
- Example:
- > inode 0 2 6 8 20
- SLOT MAJ MIN INUMB REF LINK UID GID SIZE MODE SMAJ SMIN FLAGS
- 0 001 0050 2 5 13 0 0 464 d---755 - -
- 2 001 0050 44 1 1 3 3 13472 f---700 - - txt
- 6 001 0050 204 1 2 0 0 32 d---777 - - mnt
- 8 001 0050 87 2 1 10 10 0 c---666 0004 0002
- 20 001 0050 471 1 1 3 3 50102 f---711 - - acc txt
-
- Display Mounted File System Table Entries
- Syntax: mount, m
-
- Prints the system entries for mounted on file systems. The
- device, mount point, file system sizes and free blocks and inodes
- are displayed.
-
- Example:
- > mount
- SLOT MAJ MIN INODE BUF VOLUME PACK BLOCKS INODES BFREE IFREE
- 0 1 050 0 10 7163 1808 1237 1251
- 1 1 037 6 230 usr rpp386 34000 17024 1320 14238
- 2 1 047 7 245 22950 15024 5499 9800
- 3 2 064 23 387 1200 320 210 50
-
- Display Process Table Entries
- Syntax: proc, p
-
- Prints selected running and defunct process information. The process
- ids, user ids, CPU usage, scheduling priority and wait event are
- displayed. The process name is determined by locating the user page.
-
- Example:
- > proc 0 1 2 3 4
- SLT ST PID PPID PGRP UID EUID PRI CPU EVENT NAME FLAGS
- 0 s 0 0 0 0 0 0 15 16c5c swapper incore sched
- 1 s 1 0 0 0 0 30 0 eeac init incore text
- 2 s 9389 1 9389 100 100 30 0 ef54 csh incore text
- 3 s 31 1 0 0 0 26 0 5eac logger swapped
- 4 s 30 1 0 0 0 40 0 6000000 update incore text
-
- Exit Crash Command
- Syntax: quit, q, ^D
-
- Exits Crash.
-
- Example:
- > quit
- $
-
- Print System Statics
- Syntax: stat, s
-
- Prints information regarding system name, operating system release, version,
- date of crash, and uptime at time of crash.
-
- Example:
- > stat
- sysname: XENIX
- nodename: rpp386
- release: 2.2.1
- version: SysV
- machine: i80386
- time of crash: Thu Aug 11 11:18:00 1988
- age of system: 35 days, 23 hrs., 7 mins.
-
- Print Text Table Entries
- Syntax: text, t
-
- Prints current text table entries. Cross references to inode number
- and process table entry and gives the number of processes which are
- currently referencing this table entry.
- Example:
- > text 0 1 2 3 4
- SLOT INODE REF LDREF PROC SWAPLO+ SIZE FLAGS
- 0 2 1 1 1 0 0 write
- 1 20 2 1 9 0 0 write
- 2 5 1 1 4 0 0 write
- 3 10 1 0 0 0 0 write
- 4 21 1 1 10 0 0 write
-
- Print Per Process User Page Information
- Syntax: user, u
-
- Prints the user page for the current process or a group of processes.
- The argument is the process table slot. If omitted, the currently
- running process, which will invariably be crash, user page will be
- displayed. Information includes user and system times, user and
- group ids, file I/O, system accounting and open file information.
- Provides a list of currently open files by file table entry number.
-
- Example:
- > user
- PER PROCESS USER AREA:
- USER ID's: uid: 100, gid: 0, real uid: 100, real gid: 0
- PROCESS TIMES: user: 16, sys: 22, child user: 0, child sys: 0
- PROCESS MISC: proc slot: 10, cntrl tty: maj(0) min(0)
- IPC: locks: unlocked
- FILE I/O: user addr: 25703640, file offset: 100665344, bytes: 1892,
- segment: user, umask: 22, ulimit: 2097152
- ACCOUNTING: command: crash, memory: 1987167, type: exec
- start: Thu Aug 11 11:28:10 1988
- OPEN FILES: file desc: 0 1 2 3 4 5
- file slot: 11 13 13 18 19 20
-
- Print Tunable Parameter Information
- Syntax: var, v
-
- Displays the tunable parameter values which were used at the time
- of system generation. Included are number of open files, processes
- per user, inodes, mounts, pure text entries and other related
- information.
-
- Example:
- > var
- buffers 512
- calls 30
- inodes 100
- e_inodes 100
- files 100
- e_files 100
- mounts 8
- e_mounts 8
- procs 60
- e_procs 16
- texts 40
- e_texts 40
- clists 64
- sabufs 64
- maxproc 30
- hashbuf 512
- hashmask 511
-
- Caveats and Features
-
- This release of crash is known to run under SCO Xenix 2.2.1. No other
- ports are presently known of. For the most part, porting to a different
- release of Xenix should be quite painless. The principle changes are
- likely to be in the user area and process table entries.
-
- None of the options are presently implemented. Commands which have been
- implemented have only one format.
-
- All of the commands are available as command line options. Use the one
- letter command alias as the command line option. The output defaults
- to what it would be if that one letter alias were issued to crash as a
- command. Multiple flags may be given. When in doubt, read the source.
- SHAR_EOF
- fi
- if test -f 'Makefile'
- then
- echo shar: "will not over-write existing file 'Makefile'"
- else
- cat << \SHAR_EOF > 'Makefile'
- # Your favorite Bourne Shell and Mine ...
- SHELL=/bin/sh
- # A list of all object files which need to be made
- OBJS = crash.o interact.o files.o inodes.o mounts.o procs.o texts.o \
- user.o vars.o stats.o bufs.o
- # A list of C files and such for sharchiving
- FILES = README Makefile \
- crash.c interact.c files.c inodes.c mounts.c procs.c texts.c \
- user.c vars.c stats.c bufs.c crash.h
- # C flags, suitable for debugging or production.
- CFLAGS = -c -Ox -g
-
- crash: $(OBJS)
- cc -o crash -g $(OBJS)
-
- clean:
- rm -f *.o a.out
-
- clobber: clean
- rm -f crash core
-
- shar: $(FILES)
- shar $(FILES) > crash.shar
-
- crash.o: crash.h crash.c
-
- interact.o: interact.c
-
- files.o: crash.h files.c
-
- inodes.o: crash.h inodes.c
-
- mounts.o: crash.h mounts.c
-
- procs.o: crash.h procs.c
-
- stats.o: crash.h stats.c
-
- texts.o: crash.h texts.c
-
- user.o: crash.h user.c
-
- vars.o: crash.h vars.c
-
- bufs.o: crash.h bufs.c
-
- SHAR_EOF
- fi
- if test -f 'crash.c'
- then
- echo shar: "will not over-write existing file 'crash.c'"
- else
- cat << \SHAR_EOF > 'crash.c'
- #include <sys/param.h>
- #include <sys/sysmacros.h>
- #include <sys/types.h>
- #include <sys/page.h>
- #include <sys/seg.h>
- #include <sys/proc.h>
- #include <sys/signal.h>
- #include <sys/dir.h>
- #include <sys/user.h>
- #include <sys/var.h>
- #include <sys/utsname.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include "crash.h"
-
- int memfd;
- int kmemfd;
- int swapfd;
-
- int bflag;
- int fflag;
- int iflag;
- int mflag;
- int pflag;
- int sflag;
- int tflag;
- int uflag;
- int vflag;
-
- int anyflag;
-
- struct var v;
- struct file *files;
- struct inode *inodes;
- struct text *texts;
- struct proc *procs;
- struct mount *mounts;
- struct buf *bufs;
- struct buf *bufstart;
- struct user user;
- daddr_t swplo;
- struct utsname utsname;
- time_t ktime;
- time_t klbolt;
-
- struct xlist namelist[] = {
- { 0, 0, 0, "_v" },
- { 0, 0, 0, "_file" },
- { 0, 0, 0, "_inode" },
- { 0, 0, 0, "_proc" },
- { 0, 0, 0, "_text" },
- { 0, 0, 0, "_mount" },
- { 0, 0, 0, "_bufstrt" },
- { 0, 0, 0, "_swplo" },
- { 0, 0, 0, "_time" },
- { 0, 0, 0, "_lbolt" },
- { 0, 0, 0, "_utsname" },
- { 0, 0, 0, "_u" },
- { 0, 0, 0, (char *) 0 }
- };
-
- usage ()
- {
- fprintf (stderr, "usage: crash -bfimpstv [ -N namelist ] ");
- fprintf (stderr, "[ -C corefile ] [ -S swapfile ]\n");
- exit (1);
- }
-
- r_read (fd, buf, n)
- int fd;
- char *buf;
- int n;
- {
- int i;
-
- if ((i = read (fd, buf, n)) == -1) {
- perror ("error on read");
- return (-1);
- } else
- return (i);
- }
-
- long l_lseek (fd, offs, whence)
- int fd;
- long offs;
- int whence;
- {
- long i;
- long lseek ();
-
- if ((i = lseek (fd, offs, whence)) == -1L) {
- perror ("error on lseek");
- return (-1);
- } else
- return (i);
- }
-
- main (argc, argv)
- int argc;
- char **argv;
- {
- char newname[10];
- char *namefile = "/xenix";
- char *corefile = "/dev/mem";
- char *kmemfile = "/dev/kmem";
- char *swapfile = "/dev/swap";
- int c;
- extern int optind;
- extern char *optarg;
-
- setbuf (stdout, NULL);
- setbuf (stderr, NULL);
-
- while ((c = getopt (argc, argv, "bfimpstuvN:C:S:")) != EOF) {
- switch (c) {
- case 'b':
- bflag++;
- anyflag++;
- break;
- case 'C':
- corefile = optarg;
- kmemfile = optarg;
- break;
- case 'f':
- fflag++;
- anyflag++;
- break;
- case 'i':
- iflag++;
- anyflag++;
- break;
- case 'm':
- mflag++;
- anyflag++;
- break;
- case 'N':
- namefile = optarg;
- break;
- case 'p':
- pflag++;
- anyflag++;
- break;
- case 's':
- sflag++;
- anyflag++;
- break;
- case 'S':
- swapfile = optarg;
- break;
- case 't':
- tflag++;
- anyflag++;
- break;
- case 'u':
- uflag++;
- anyflag++;
- break;
- case 'v':
- vflag++;
- anyflag++;
- break;
- default:
- usage ();
- }
- }
- if (xlist (namefile, namelist) != 0) {
- perror ("pstat: namelist");
- exit (1);
- }
- if ((memfd = open (corefile, O_RDONLY)) < 0) {
- perror ("pstat: corefile");
- exit (1);
- }
- if ((kmemfd = open (kmemfile, O_RDONLY)) < 0) {
- perror ("pstat: kmemfile");
- exit (1);
- }
- if ((swapfd = open (swapfile, O_RDONLY)) < 0) {
- perror ("pstat: swapfile");
- exit (1);
- }
- l_lseek (kmemfd, namelist[NM_V].xl_value, 0);
- r_read (kmemfd, &v, sizeof v);
- l_lseek (kmemfd, namelist[NM_SWPLO].xl_value, 0);
- r_read (kmemfd, &swplo, sizeof swplo);
-
- if (bflag)
- prbufs ((int *) 0, 0);
-
- if (fflag)
- prfiles ((int *) 0, 0);
-
- if (iflag)
- prinodes ((int *) 0, 0);
-
- if (mflag)
- prmounts ((int *) 0, 0);
-
- if (pflag)
- prprocs ((int *) 0, 0);
-
- if (sflag)
- prstats ((int *) 0, 0);
-
- if (tflag)
- prtexts ((int *) 0, 0);
-
- if (uflag)
- prusers ((int *) 0, 0);
-
- if (vflag)
- prvars ((int *) 0, 0);
-
- if (! anyflag) {
- interact ();
- exit (0);
- } else {
- exit (0);
- }
- }
- SHAR_EOF
- fi
- if test -f 'interact.c'
- then
- echo shar: "will not over-write existing file 'interact.c'"
- else
- cat << \SHAR_EOF > 'interact.c'
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include <setjmp.h>
- #include <signal.h>
-
- extern prbufs ();
- extern prfiles ();
- extern prinodes ();
- extern prmounts ();
- extern prprocs ();
- extern prstats ();
- extern prtexts ();
- extern prusers ();
- extern prvars ();
- extern quit ();
- extern help ();
- extern int errno;
-
- jmp_buf del;
- int delflag;
-
- struct func {
- void (*f_func)();
- char *f_name;
- };
-
- struct func commands[] = {
- { prbufs, "b" },
- { prbufs, "buf" },
- { prfiles, "f" },
- { prfiles, "file" },
- { help, "h" },
- { help, "help" },
- { prinodes, "i" },
- { prinodes, "ino" },
- { prinodes, "inode" },
- { prmounts, "m" },
- { prmounts, "mount" },
- { prprocs, "p" },
- { prprocs, "proc" },
- { quit, "q" },
- { quit, "quit" },
- { prstats, "s" },
- { prstats, "stat" },
- { prtexts, "t" },
- { prtexts, "text" },
- { prusers, "u" },
- { prusers, "user" },
- { prvars, "v" },
- { prvars, "var" },
- { 0, 0 }
- };
-
- help ()
- {
- printf ("command summary\n\n");
-
- printf ("buf (b) - buffer headers\n");
- printf ("file (f) - open files\n");
- printf ("help (h,?) - list commands\n");
- printf ("inode (ino,i) - active inodes\n");
- printf ("mount (m) - mounted file systems\n");
- printf ("proc (p) - active and defunct processes\n");
- printf ("quit (q,^D) - exit crash\n");
- printf ("stat (s) - crash statistics, age, time\n");
- printf ("text (t) - active and sticky bit text segments\n");
- printf ("user (u) - user page information\n");
- printf ("var (v) - tunable parameters\n");
- }
-
- quit ()
- {
- exit (0);
- }
-
- interupt (sig)
- int sig;
- {
- delflag = 1;
- fflush (stdout);
- fflush (stderr);
- longjmp (del, sig);
- }
-
- interact ()
- {
- int i;
- int items[100];
- int cnt;
- char *cp;
- char *com;
- char *num;
- char buf[BUFSIZ];
-
- while (setjmp (del)) /* catch that first interupt */
- fprintf (stderr, "\nq to quit\n");
-
- signal (SIGINT, interupt); /* and setup the handler */
-
- while (fprintf (stderr, "> "), gets (buf) != (char *) 0) {
- while (setjmp (del))
- goto eh;
-
- /*
- * make all commands lower case.
- */
-
- for (i = strlen (buf) - 1;i >= 0;i--)
- if (isupper (buf[i]))
- buf[i] = tolower (buf[i]);
-
- /*
- * find first non-white space character and skip if
- * a blank line
- */
-
- for (com = buf;*com && (*com == ' ' || *com == '\t');com++)
- ;
-
- if (*com == '\0')
- continue;
-
- /*
- * find the entire command word
- */
-
- if (*com == '?') {
- help ();
- continue;
- }
-
- for (cp = com;*cp >= 'a' && *cp <= 'z';cp++)
- ;
-
- if (*cp != '\0') {
- *cp++ = '\0';
-
- /*
- * tokenize the remainder of the string into numbers
- */
-
- for (cnt = 0;*cp && cnt < 100;cnt++) {
- for (;*cp && isspace (*cp);cp++)
- ;
-
- for (num = cp;*cp && isdigit (*cp);cp++)
- ;
-
- if (*cp && ! isspace (*cp))
- goto eh;
-
- if (*cp)
- *cp++ = '\0';
-
- items[cnt] = atoi (num);
- }
- } else {
- cnt = 0;
- }
-
- for (i = 0;commands[i].f_name != (char *) 0;i++)
- if (strcmp (commands[i].f_name, com) == 0)
- break;
-
- if (commands[i].f_name == (char *) 0)
- goto eh;
-
- (*commands[i].f_func) (items, cnt);
- continue;
-
- /*
- * common error handler. get here if an error is found.
- */
- eh:
- if (delflag) {
- putc ('\n', stderr);
- delflag = 0;
- }
- fprintf (stderr, "eh?\n");
- signal (SIGINT, interupt);
- }
- }
- SHAR_EOF
- fi
- if test -f 'files.c'
- then
- echo shar: "will not over-write existing file 'files.c'"
- else
- cat << \SHAR_EOF > 'files.c'
- #include <sys/param.h>
- #include <sys/sysmacros.h>
- #include <sys/types.h>
- #include <sys/var.h>
- #include <sys/inode.h>
- #include <sys/file.h>
- #include <sys/page.h>
- #include <sys/seg.h>
- #include <sys/signal.h>
- #include <sys/dir.h>
- #include <sys/user.h>
- #include "crash.h"
-
- prfiles (items, cnt)
- int *items;
- int cnt;
- {
- int i;
-
- files = (struct file *) malloc (v.v_file * sizeof (struct file));
- l_lseek (kmemfd, namelist[NM_FILE].xl_value, 0);
- r_read (kmemfd, files, sizeof (struct file) * v.v_file);
-
- printf ("SLOT FLAG COUNT INODE OFFSET\n");
- if (cnt == 0) {
- for (i = 0;i < v.v_file;i++) {
- if (files[i].f_count == 0 || files[i].f_flag == 0)
- continue;
-
- dofile (i);
- }
- } else {
- for (i = 0;i < cnt;i++) {
- if (items[i] >= v.v_file)
- printf ("value (%d) out of range\n", items[i]);
- else
- dofile (items[i]);
- }
- }
- free ((char *) files);
- }
-
-
- dofile (i)
- int i;
- {
- printf ("%4d %03o %c%c%c%c%c%c%c%c %5d %5d %10ld\n",
- i, files[i].f_flag & FMASK,
- (files[i].f_flag & FREAD) ? 'R':' ',
- (files[i].f_flag & FWRITE) ? 'W':' ',
- (files[i].f_flag & FNDELAY) ? 'N':' ',
- (files[i].f_flag & FAPPEND) ? 'A':' ',
- (files[i].f_flag & FSYNC) ? 'S':' ',
- (files[i].f_flag & FCREAT) ? 'C':' ',
- (files[i].f_flag & FTRUNC) ? 'T':' ',
- (files[i].f_flag & FEXCL) ? 'X':' ',
- files[i].f_count,
- files[i].f_inode - (struct inode *) namelist[NM_INODE].xl_value,
- files[i].f_offset);
- }
- SHAR_EOF
- fi
- if test -f 'inodes.c'
- then
- echo shar: "will not over-write existing file 'inodes.c'"
- else
- cat << \SHAR_EOF > 'inodes.c'
- #include <sys/param.h>
- #include <sys/sysmacros.h>
- #include <sys/types.h>
- #include <sys/var.h>
- #include <sys/inode.h>
- #include <a.out.h>
- #include "crash.h"
-
- prinodes (items, cnt)
- int *items;
- int cnt;
- {
- int i;
-
- inodes = (struct inode *) malloc (v.v_inode * sizeof (struct inode));
- l_lseek (kmemfd, namelist[NM_INODE].xl_value, 0);
- r_read (kmemfd, inodes, sizeof (struct inode) * v.v_inode);
-
- printf ("SLOT MAJ MIN INUMB REF LINK UID GID SIZE MODE SMAJ SMIN FLAGS\n");
-
- if (cnt == 0) {
- for (i = 0;i < v.v_inode;i++) {
- if (inodes[i].i_count == 0)
- continue;
-
- doinode (i);
- }
- } else {
- for (i = 0;i < cnt;i++) {
- if (items[i] >= v.v_inode)
- printf ("value (%d) out of range\n", items[i]);
- else
- doinode (items[i]);
- }
- }
- free ((char *) inodes);
- }
-
- doinode (i)
- int i;
- {
- char *modes = " pcCd bBf";
- struct inode *ip;
-
- ip = &inodes[i];
-
- printf ("%4d %03o %04o %5d %3d %4d%5d%5d %8ld %c%c%c%c%03o",
- i, major (ip->i_dev), minor (ip->i_dev), ip->i_number,
- ip->i_count, ip->i_nlink, ip->i_uid, ip->i_gid,
- ip->i_size,
- modes[(ip->i_mode & IFMT) >> 12],
- (ip->i_mode & ISUID) ? 'u':'-',
- (ip->i_mode & ISGID) ? 'g':'-',
- (ip->i_mode & ISVTX) ? 't':'-',
- (ip->i_mode & 0777));
-
- if (! (((ip->i_mode & IFMT) == IFDIR) ||
- ((ip->i_mode & IFMT) == IFREG) ||
- ((ip->i_mode & IFMT) == IFIFO)))
- printf (" %04o %04o", major (ip->i_rdev),
- minor (ip->i_rdev));
- else
- printf (" - -"); /* special file stuff */
- if (ip->i_flag & IUPD) printf (" upd");
- if (ip->i_flag & IACC) printf (" acc");
- if (ip->i_flag & ICHG) printf (" chg");
- if (ip->i_flag & IMOUNT) printf (" mnt");
- if (ip->i_flag & ITEXT) printf (" txt");
- if (ip->i_flag & ILOCK) printf (" lck");
- #ifdef ISYN
- if (ip->i_flag & ISYN) printf (" syn");
- #endif
- #ifdef IRMT
- if (ip->i_flag & IRMT) printf (" rmt");
- #endif
- if (ip->i_flag & IWANT) printf (" wnt");
-
- printf ("\n");
- }
- SHAR_EOF
- fi
- if test -f 'mounts.c'
- then
- echo shar: "will not over-write existing file 'mounts.c'"
- else
- cat << \SHAR_EOF > 'mounts.c'
- #include <sys/param.h>
- #include <sys/sysmacros.h>
- #include <sys/types.h>
- #include <sys/var.h>
- #include <sys/inode.h>
- #include <sys/ino.h>
- #include <sys/buf.h>
- #include <sys/filsys.h>
- #include <sys/mount.h>
- #include <a.out.h>
- #include "crash.h"
-
- prmounts (items, cnt)
- int *items;
- int cnt;
- {
- int i;
-
- mounts = (struct mount *) malloc (v.v_mount * sizeof (struct mount));
- l_lseek (kmemfd, namelist[NM_MOUNT].xl_value, 0);
- r_read (kmemfd, mounts, sizeof (struct mount) * v.v_mount);
- l_lseek (kmemfd, namelist[NM_BUFFER].xl_value, 0);
- r_read (kmemfd, &bufstart, sizeof bufstart);
-
- printf ("SLOT MAJ MIN INODE BUF VOLUME PACK BLOCKS INODES BFREE IFREE\n");
-
- if (cnt == 0) {
- for (i = 0;i < v.v_mount;i++) {
- if (mounts[i].m_flags == 0)
- continue;
-
- domount (i);
- }
- } else {
- for (i = 0;i < cnt;i++) {
- if (items[i] >= v.v_mount)
- printf ("value (%d) out of range\n", items[i]);
- else
- domount (items[i]);
- }
- }
- free ((char *) mounts);
- }
-
- domount (i)
- int i;
- {
- struct filsys filsys;
- struct buf buf;
- struct inode *ip = (struct inode *) namelist[NM_INODE].xl_value;
-
- printf ("%4d %4o %03o %6d %4d",
- i, major (mounts[i].m_dev), minor (mounts[i].m_dev),
- mounts[i].m_inodp ?
- mounts[i].m_inodp - ip : 0,
- mounts[i].m_bufp ?
- mounts[i].m_bufp - bufstart : 0);
-
- /*
- * zero before using since unused mount entries don't have
- * buffers and such.
- */
-
- memset (&buf, 0, sizeof buf);
- memset (&filsys, 0, sizeof filsys);
-
- if (mounts[i].m_flags != 0) {
- l_lseek (memfd, (long) mounts[i].m_bufp, 0);
- r_read (memfd, &buf, sizeof buf);
- l_lseek (memfd, (long) buf.b_paddr, 0);
- r_read (memfd, &filsys, sizeof filsys);
- }
- printf (" %-6.6s %-6.6s",
- filsys.s_fname, filsys.s_fpack);
-
- printf (" %6ld %6ld %6ld %6ld",
- filsys.s_fsize, INOPB * filsys.s_isize,
- (long) filsys.s_tfree, (long) filsys.s_tinode);
-
- putchar ('\n');
- }
- SHAR_EOF
- fi
- if test -f 'procs.c'
- then
- echo shar: "will not over-write existing file 'procs.c'"
- else
- cat << \SHAR_EOF > 'procs.c'
- #include <sys/param.h>
- #include <sys/sysmacros.h>
- #include <sys/types.h>
- #include <sys/var.h>
- #include <sys/text.h>
- #include <sys/page.h>
- #include <sys/seg.h>
- #include <sys/proc.h>
- #include <sys/signal.h>
- #include <sys/dir.h>
- #include <sys/user.h>
- #include "crash.h"
-
- /*
- * prprocs - output the process table
- */
-
- prprocs (items, cnt)
- int *items;
- int cnt;
- {
- struct proc *pp;
- struct user user;
- int i;
-
- procs = (struct proc *) malloc (v.v_proc * sizeof (struct proc));
- lseek (kmemfd, namelist[NM_PROC].xl_value, 0);
- read (kmemfd, procs, sizeof (struct proc) * v.v_proc);
-
- printf ("SLT ST PID PPID PGRP UID EUID PRI CPU EVENT NAME FLAGS\n");
-
- if (cnt == 0) {
- for (i = 0;i < v.v_proc;i++) {
- if (procs[i].p_stat == 0)
- continue;
-
- doproc (i);
- }
- } else {
- for (i = 0;i < cnt;i++) {
- if (items[i] >= v.v_proc)
- printf ("value (%d) out of range\n", items[i]);
- else
- doproc (items[i]);
- }
- }
- free ((char *) procs);
- }
-
- doproc (i)
- int i;
- {
- struct proc *pp;
-
- pp = &procs[i];
-
- printf ("%3d %c %5d %5d %5d %5d %5d %3d %3d", i,
- " swriztBST"[pp->p_stat], pp->p_pid, pp->p_ppid,
- pp->p_pgrp, pp->p_uid, pp->p_suid,
- pp->p_pri & 0377, pp->p_cpu & 0377);
-
- if (pp->p_wchan)
- printf (" %8x", pp->p_wchan);
- else
- printf (" ");
-
- if (pp->p_stat == SZOMB) {
- printf (" ZOMBIE ");
- } else if (pp->p_flag & SSYS) {
- printf (" swapper ");
- } else if (pp->p_stat != 0) {
- if (findu (pp, i, &user))
- printf (" %-10.10s", user.u_comm);
- else
- printf (" SWAPPED ");
- } else {
- printf (" ");
- }
- if (pp->p_stat == SRUN) printf (" running");
- if (pp->p_stat == SZOMB) printf (" zombie");
- if (pp->p_flag & SLOAD) printf (" incore");
- else printf (" swapped");
- if (pp->p_flag & SSYS) printf (" sched");
- if (pp->p_flag & SLOCK) printf (" locked");
- if (pp->p_flag & STRC) printf (" traced");
- if (pp->p_flag & SWTED) printf (" wanted");
- if (pp->p_flag & STEXT) printf (" text");
- if (pp->p_flag & SSPART) printf (" part-swap");
-
- printf ("\n");
- }
- SHAR_EOF
- fi
- if test -f 'texts.c'
- then
- echo shar: "will not over-write existing file 'texts.c'"
- else
- cat << \SHAR_EOF > 'texts.c'
- #include <sys/param.h>
- #include <sys/sysmacros.h>
- #include <sys/types.h>
- #include <sys/var.h>
- #include <sys/inode.h>
- #include <sys/text.h>
- #include <sys/page.h>
- #include <sys/seg.h>
- #include <sys/proc.h>
- #include <a.out.h>
- #include "crash.h"
-
- prtexts (items, cnt)
- int *items;
- int cnt;
- {
- int i;
-
- texts = (struct text *) malloc (v.v_text * sizeof (struct text));
- lseek (kmemfd, namelist[NM_TEXT].xl_value, 0);
- read (kmemfd, texts, sizeof (struct text) * v.v_text);
-
- printf ("SLOT INODE REF LDREF PROC SWAPLO+ SIZE FLAGS\n");
-
- if (cnt == 0) {
- for (i = 0;i < v.v_text;i++) {
- if (texts[i].x_count == 0)
- continue;
-
- dotext (i);
- }
- } else {
- for (i = 0;i < cnt;i++) {
- if (items[i] >= v.v_text)
- printf ("value (%d) out of range\n", items[i]);
- else
- dotext (items[i]);
- }
- }
- free ((char *) texts);
- }
-
- dotext (i)
- int i;
- {
- struct text *tp;
- int procnum;
-
- tp = &texts[i];
-
- if (tp->x_ccount > 0)
- procnum = tp->x_caddr -
- (struct proc *) namelist[NM_PROC].xl_value;
- else
- procnum = 0;
-
- printf ("%4d %5d %3d %5d %4d %7d %5d ", i,
- tp->x_iptr - (struct inode *) namelist[NM_INODE].xl_value,
- tp->x_count, tp->x_ccount, procnum,
- tp->x_daddr, tp->x_size);
-
- if (tp->x_flag & XTRC) printf (" trace");
- if (tp->x_flag & XWRIT) printf (" write");
- if (tp->x_flag & XLOAD) printf (" loaded");
- if (tp->x_flag & XLOCK) printf (" locked");
- if (tp->x_flag & XWANT) printf (" wanted");
- if (tp->x_flag & XLARGE) printf (" large");
- if (tp->x_flag & XFPU) printf (" fpu");
-
- printf ("\n");
- }
- SHAR_EOF
- fi
- if test -f 'user.c'
- then
- echo shar: "will not over-write existing file 'user.c'"
- else
- cat << \SHAR_EOF > 'user.c'
- #include <sys/param.h>
- #include <sys/sysmacros.h>
- #include <sys/types.h>
- #include <sys/page.h>
- #include <sys/seg.h>
- #include <sys/file.h>
- #include <sys/proc.h>
- #include <sys/signal.h>
- #include <sys/dir.h>
- #include <sys/user.h>
- #include <sys/var.h>
- #include <sys/lock.h>
- #include "crash.h"
-
- findu (proc, slot, user)
- struct proc *proc;
- int slot;
- struct user *user;
- {
- struct proc *procs = (struct proc *) namelist[NM_PROC].xl_value;
- long swapaddr;
- int i;
-
- if ((proc->p_flag & (SSWAP|SSPART)) || ! (proc->p_flag & SLOAD)) {
- swapaddr = proc->p_addr[0].te_frameno * NBPC;
- l_lseek (swapfd, swapaddr, 0);
- r_read (swapfd, user, sizeof *user);
- } else {
- l_lseek (memfd, proc->p_addr[0].te_frameno * NBPC, 0);
- r_read (memfd, user, sizeof *user);
- }
- if (user->u_procp - procs == slot)
- return (1);
- else
- return (0);
- }
-
- prusers (items, cnt)
- int *items;
- int cnt;
- {
- int i;
-
- if (cnt == 0) {
- douser (-1);
- return (1);
- }
- for (i = 0;i < cnt;i++) {
- if (items[i] >= v.v_proc) {
- printf ("value (%d) out of range\n", items[i]);
- continue;
- } else {
- douser (items[i]);
- }
- }
- }
-
- douser (i)
- {
- struct file *fp;
- struct proc proc;
- struct proc *pp;
- static char *segments[] = { "user", "system", "user i" };
- int fileno;
-
- pp = (struct proc *) namelist[NM_PROC].xl_value;
- fp = (struct file *) namelist[NM_FILE].xl_value;
-
- if (i >= 0) {
- l_lseek (kmemfd, (long) &pp[i], 0);
- r_read (kmemfd, &proc, sizeof proc);
-
- if (! findu (&proc, i, &user))
- return (0);
- } else {
- l_lseek (kmemfd, namelist[NM_USER].xl_value, 0);
- r_read (kmemfd, &user, sizeof user);
- }
- printf ("PER PROCESS USER AREA:\n");
- printf ("USER ID's: uid: %d, gid: %d, real uid: %d, real gid: %d\n",
- user.u_uid, user.u_gid, user.u_ruid, user.u_rgid);
- printf ("PROCESS TIMES: user: %d, sys: %d, child user: %d, child sys: %d\n",
- user.u_utime, user.u_stime, user.u_cutime, user.u_cstime);
- printf ("PROCESS MISC: proc slot: %d, cntrl tty: maj(%d) min(%d)\n",
- user.u_procp - pp, major (user.u_ttyd), minor (user.u_ttyd));
- printf ("IPC: locks:%s%s%s%s%s\n",
- user.u_lock == UNLOCK ? " unlocked":"",
- user.u_lock & PROCLOCK ? " proc":"",
- user.u_lock & TXTLOCK ? " text":"",
- user.u_lock & DATLOCK ? " data":"",
- user.u_lock & HUGELOCK ? " huge":"");
- printf ("FILE I/O: user addr: %ld, file offset: %ld, bytes: %ld,\n",
- user.u_baseu, user.u_offset, user.u_count);
- printf (" segment: %s, umask: %01o, ulimit: %ld\n",
- segments[user.u_segflg], user.u_cmask, user.u_limit);
- printf ("ACCOUNTING: command: %s, memory: %ld, type: %s\n",
- user.u_comm, user.u_mem, user.u_acflag ? "fork":"exec");
- printf (" start: %s",
- ctime (&user.u_start));
-
- printf ("OPEN FILES: file desc: ");
- for (i = 0;i < NOFILE;i++)
- if (user.u_ofile[i] != (struct file *) 0)
- printf ("%4d", i);
- putchar ('\n');
-
- printf (" file slot: ");
- for (i = 0;i < NOFILE;i++)
- if (user.u_ofile[i] != (struct file *) 0)
- printf ("%4d", user.u_ofile[i] - fp);
- putchar ('\n');
-
- return (0);
- }
- SHAR_EOF
- fi
- if test -f 'vars.c'
- then
- echo shar: "will not over-write existing file 'vars.c'"
- else
- cat << \SHAR_EOF > 'vars.c'
- #include <sys/param.h>
- #include <sys/sysmacros.h>
- #include <sys/types.h>
- #include <sys/file.h>
- #include <sys/inode.h>
- #include <sys/page.h>
- #include <sys/seg.h>
- #include <sys/proc.h>
- #include <sys/text.h>
- #include <sys/mount.h>
- #include <sys/var.h>
- #include <a.out.h>
- #include "crash.h"
-
- prvars ()
- {
- printf ("buffers %3d\n",
- v.v_buf);
- printf ("calls %3d\n",
- v.v_call);
- printf ("inodes %3d\n",
- v.v_inode);
- printf ("e_inodes %3d\n",
- v.ve_inode - (struct inode *) namelist[NM_INODE].xl_value);
- printf ("files %3d\n",
- v.v_file);
- printf ("e_files %3d\n",
- v.ve_file - (struct file *) namelist[NM_FILE].xl_value);
- printf ("mounts %3d\n",
- v.v_mount);
- printf ("e_mounts %3d\n",
- v.ve_mount - (struct mount *) namelist[NM_MOUNT].xl_value);
- printf ("procs %3d\n",
- v.v_proc);
- printf ("e_procs %3d\n",
- v.ve_proc - (struct proc *) namelist[NM_PROC].xl_value);
- printf ("texts %3d\n",
- v.v_text);
- printf ("e_texts %3d\n",
- v.ve_text - (struct text *) namelist[NM_TEXT].xl_value);
- printf ("clists %3d\n",
- v.v_clist);
- printf ("sabufs %3d\n",
- v.v_sabuf);
- printf ("maxproc %3d\n",
- v.v_maxup);
- /*
- swapmap 105
- */
- printf ("hashbuf %3d\n",
- v.v_hbuf);
- printf ("hashmask %3d\n",
- v.v_hmask);
- }
- SHAR_EOF
- fi
- if test -f 'stats.c'
- then
- echo shar: "will not over-write existing file 'stats.c'"
- else
- cat << \SHAR_EOF > 'stats.c'
- #include <sys/param.h>
- #include <sys/sysmacros.h>
- #include <sys/types.h>
- #include <sys/utsname.h>
- #include <sys/param.h>
- #include <a.out.h>
- #include <time.h>
- #include "crash.h"
-
- #define MINUTE (60L)
- #define HOUR (MINUTE*60L)
- #define DAY (HOUR*24L)
-
- prstats ()
- {
- l_lseek (kmemfd, namelist[NM_UTSNAME].xl_value, 0);
- r_read (kmemfd, &utsname, sizeof utsname);
-
- l_lseek (kmemfd, namelist[NM_TIME].xl_value, 0);
- r_read (kmemfd, &ktime, sizeof ktime);
-
- l_lseek (kmemfd, namelist[NM_LBOLT].xl_value, 0);
- r_read (kmemfd, &klbolt, sizeof klbolt);
-
- printf (" sysname: %.*s\n",
- sizeof utsname.sysname, utsname.sysname);
- printf (" nodename: %.*s\n",
- sizeof utsname.nodename, utsname.nodename);
- printf (" release: %.*s\n",
- sizeof utsname.release, utsname.release);
- printf (" version: %.*s\n",
- sizeof utsname.version, utsname.version);
- printf (" machine: %.*s\n",
- sizeof utsname.machine, utsname.machine);
-
- printf (" time of crash: %s", ctime (&ktime));
-
- klbolt /= HZ; /* convert to seconds */
-
- printf (" age of system:");
-
- if (klbolt >= DAY)
- printf (" %d %s,", klbolt / DAY,
- klbolt >= (2*DAY) ? "days":"day");
-
- klbolt %= DAY;
-
- if (klbolt >= HOUR)
- printf (" %d %s,", klbolt / HOUR,
- klbolt >= (2*HOUR) ? "hrs.":"hr.");
-
- klbolt %= HOUR;
- klbolt /= MINUTE;
-
- printf (" %d %s\n", klbolt,
- klbolt == 0 || klbolt >= 2 ? "mins.":"min.");
- }
- SHAR_EOF
- fi
- if test -f 'bufs.c'
- then
- echo shar: "will not over-write existing file 'bufs.c'"
- else
- cat << \SHAR_EOF > 'bufs.c'
- #include <sys/param.h>
- #include <sys/sysmacros.h>
- #include <sys/types.h>
- #include <sys/var.h>
- #include <sys/inode.h>
- #include <sys/ino.h>
- #include <sys/buf.h>
- #include <a.out.h>
- #include "crash.h"
-
- prbufs (items, cnt)
- int *items;
- int cnt;
- {
- int i;
-
- bufs = (struct buf *) malloc (v.v_buf * sizeof (struct buf));
-
- l_lseek (kmemfd, namelist[NM_BUFFER].xl_value, 0);
- r_read (kmemfd, &bufstart, sizeof bufstart);
-
- l_lseek (memfd, bufstart, 0);
- r_read (memfd, bufs, v.v_buf * sizeof (struct buf));
-
- printf (" BUF MAJ MIN BLOCK FLAGS\n");
-
- if (cnt == 0) {
- for (i = 0;i < v.v_buf;i++) {
- if (bufs[i].b_flags == 0)
- continue;
-
- dobuf (i);
- }
- } else {
- for (i = 0;i < cnt;i++) {
- if (items[i] >= v.v_buf)
- printf ("value (%d) out of range\n", items[i]);
- else
- dobuf (items[i]);
- }
- }
- free ((char *) bufs);
- }
-
- dobuf (i)
- int i;
- {
- struct buf *bp;
-
- bp = &bufs[i];
-
- printf ("%4d %03.3o %04.4o %8d",
- i, major (bp->b_dev) & 0377, minor (bp->b_dev), bp->b_blkno);
-
- if (bp->b_flags & B_READ) printf (" read");
- if (bp->b_flags & B_DONE) printf (" done");
- if (bp->b_flags & B_ERROR) printf (" error");
- if (bp->b_flags & B_BUSY) printf (" busy");
- if (bp->b_flags & B_PHYS) printf (" phys");
- if (bp->b_flags & B_MAP) printf (" map");
- if (bp->b_flags & B_WANTED) printf (" wanted");
- if (bp->b_flags & B_AGE) printf (" age");
- if (bp->b_flags & B_ASYNC) printf (" async");
- if (bp->b_flags & B_DELWRI) printf (" delwri");
- if (bp->b_flags & B_OPEN) printf (" open");
- if (bp->b_flags & B_STALE) printf (" stale");
- if (bp->b_flags & B_NOCROSS) printf (" nocross");
- if (bp->b_flags & B_FLUSH) printf (" flush");
-
- putchar ('\n');
- }
- SHAR_EOF
- fi
- if test -f 'crash.h'
- then
- echo shar: "will not over-write existing file 'crash.h'"
- else
- cat << \SHAR_EOF > 'crash.h'
- extern int memfd;
- extern int kmemfd;
- extern int swapfd;
-
- #define NM_V 0
- #define NM_FILE 1
- #define NM_INODE 2
- #define NM_PROC 3
- #define NM_TEXT 4
- #define NM_MOUNT 5
- #define NM_BUFFER 6
- #define NM_SWPLO 7
- #define NM_TIME 8
- #define NM_LBOLT 9
- #define NM_UTSNAME 10
- #define NM_USER 11
- #define NM_NAMES 12
-
- extern struct xlist namelist[];
- extern struct var v;
- extern struct file *files;
- extern struct inode *inodes;
- extern struct text *texts;
- extern struct proc *procs;
- extern struct mount *mounts;
- extern struct buf *bufs;
- extern struct buf *bufstart;
- extern struct user user;
- extern daddr_t swplo;
- extern time_t ktime;
- extern time_t klbolt;
- extern struct utsname utsname;
- SHAR_EOF
- fi
- exit 0
- # End of shell archive
-